<?php
/**
 * Created by PhpStorm.
 * User: wodrow
 * Date: 19-11-11
 * Time: 下午6:03
 */

namespace common\components;


use common\data\Enum;
use common\models\db\LogEmailSend;
use common\models\db\User;
use GuzzleHttp\Client;
use wodrow\yii2wtools\tools\ArrayHelper;
use wodrow\yii2wtools\tools\FileHelper;
use wodrow\yii2wtools\tools\Model;
use yii\base\Component;

/**
 * Class ApiTool
 * @package common\components
 *
 * @property-read string $randomAvatarUrl
 */
class ApiTool extends Component
{
    public $baseUri;
    public $apiUri;
    public $isEmailCodeSend = true;

    /**
     * @param $uri
     * @param $form_params
     * @return mixed
     * @throws
     */
    public function post($uri, $form_params, $user = null)
    {
        $client = new Client(['base_uri' => $this->getFullUrl($uri), 'verify'=>false]);
        $form_params = $this->signFormParams($form_params, $user);
        $resp = $client->request("POST", "", [
            'form_params' => $form_params,
        ]);
        $resp_content = $resp->getBody()->getContents();
        return json_decode($resp_content, true);
    }

    /**
     * @param $form_params
     * @return array
     */
    public function signFormParams($form_params, $user = null)
    {
        if ($user){
            $form_params = $this->generateFormParams($user, $form_params);
        }
        return $form_params;
    }

    /**
     * @param $user
     * @param array $form_params
     * @return array
     */
    public function generateFormParams($user, $form_params = [])
    {
        $form_params['token'] = $user->token;
        $form_params['timestamp'] = YII_BT_TIME;
        $form_params['nonce'] = $form_params['timestamp'].rand(1000, 4000);
        $p = $form_params;
        $p['key'] = $user->key;
        ksort($p);
        unset($p['sign']);
        $p_arr = [];
        foreach ($p as $k => $v) {
            $p_arr[] = $k."=".$v;
        }
        $p_str = ArrayHelper::arr2str($p_arr, '&');
        $form_params['sign'] = md5($p_str);
        return $form_params;
    }

    /**
     * @param string $email
     * @param int $typeKey
     * @param int $mininterval 最短间隔s
     * @param int $max_count_in24 24小时之内相同邮箱最多发送次数
     * @param int $duration 有效期s
     * @return array|mixed
     * @return int status
     * @return string msg
     * @throws
     */
    public function sendEmailCode($email, $typeKey, $mininterval = 600, $max_count_in24 = 3, $duration = 3600)
    {
        $r = [
            'status' => 0,
            'msg' => "",
        ];
        $types = Enum::getEmailSendTypeDesc();
        $val = $types[$typeKey];
        $query = LogEmailSend::find()->where(['to' => $email, 'type' => $typeKey]);
        $send_total_in24 = $query->andWhere(['>', 'created_at', YII_BT_TIME - 86400])->count();
        if ($send_total_in24 >= $max_count_in24){
            $r['msg'] = "24小时之内相同邮箱发送{$val}验证码不能超过{$max_count_in24}次";
            return $r;
        }
        $lastSendLog = $query->orderBy(['id' => SORT_DESC])->one();
        if ($lastSendLog && YII_BT_TIME - $lastSendLog->created_at < $mininterval){
            $r['msg'] = "{$mininterval}秒内相同邮箱不能重复发送{$val}验证码";
            return $r;
        }
        $mail = \Yii::$app->mailer->compose();
        $log = new LogEmailSend();
        $log->created_at = YII_BT_TIME;
        $log->subject = "{$val}验证码";
        $log->from = json_encode($mail->getFrom(), JSON_UNESCAPED_UNICODE);
        $log->to = $email;
        $log->type = $typeKey;
        $log->code = rand(100000, 999999);
        $log->duration = $duration;
        if (!$this->isEmailCodeSend){
            $log->status = LogEmailSend::STATUS_SEND_SUCCESS;
            $log->send_msg = "当前环境{$val}验证码为:{$log->code},有效期{$duration}秒,正式环境会直接把验证码发送到邮箱";
            $r['status'] = 200;
            $r['msg'] = $log->send_msg;
        }else{
            $log->send_msg = "{$val}验证码:{$log->code},有效期{$duration}秒";
            $mail->setTo($log->to);
            $mail->setSubject($log->subject);
            $mail->setTextBody($log->send_msg);
            $_r = $mail->send();
            if ($_r){
                $r['status'] = 200;
                $r['msg'] = "发送{$val}验证码成功";
                $log->status = LogEmailSend::STATUS_SEND_SUCCESS;
            }else{
                $r['status'] = 0;
                $r['msg'] = "发送{$val}验证码失败";
                $log->status = LogEmailSend::STATUS_SEND_FAILED;
            }
        }
        $log->params = json_encode([
            'mininterval' => $mininterval,
            'send_total_in24' => $send_total_in24,
            'max_count_in24' => $max_count_in24,
        ], JSON_UNESCAPED_UNICODE);
        if (!$log->save()){
            $r['status'] = 0;
            $r['msg'] = Model::getModelError($log);
        }
        return $r;
    }

    /**
     * @param $email
     * @param $typeKey
     * @param $code
     * @param $timeout
     * @return bool
     */
    public function validateEmailCode($email, $typeKey, $code)
    {
        $query = LogEmailSend::find()->where(['to' => $email, 'type' => $typeKey]);
        $lastSendLog = $query->orderBy(['id' => SORT_DESC])->one();
        if (!$lastSendLog){
            return false;
        }
        if (YII_BT_TIME - $lastSendLog->created_at > $lastSendLog->duration){
            return false;
        }
        if ($lastSendLog->code != $code){
            return false;
        }
        return true;
    }

    /**
     * @param User $user
     * @return array
     *
     */
    public function authReturn($user, $isYour = true)
    {
        $r = [
            'id' => $user->id,
            'token' => $user->token,
            'key' => $user->key,
            'username' => $user->username,
            'nickName' => $user->nickName,
            'email' => $user->email,
            'amount' => $user->amount,
            'frozen' => $user->frozen,
            'status' => $user->status,
            'created_at' => $user->created_at,
            'avatar' => $user->avatar,
            'mobile' => $user->mobile,
            'weixin' => $user->weixin,
            'qq' => $user->qq,
            'alipay_exceptional_code' => $user->alipay_exceptional_code,
            'alipay_exceptional_url' => $user->alipay_exceptional_url,
            'weixin_exceptional_code' => $user->weixin_exceptional_code,
            'weixin_exceptional_url' => $user->weixin_exceptional_url,
        ];
        if (!$isYour){
            unset($r['token']);
            unset($r['key']);
        }
        return $r;
    }

    /**
     * @param $uri
     * @return string
     */
    public function getFullUrl($uri = "")
    {
        return $this->baseUri.$this->apiUri.$uri;
    }

    /**
     * @return string
     */
    public function getRandomAvatarUrl()
    {
        $baseRoot = \Yii::getAlias("@static_root/avatars");
        $baseUrl = \Yii::getAlias("@static_url/avatars");
        $avatars = FileHelper::listDir($baseRoot);
        $avatar = $avatars[array_rand($avatars)];
        $avatar = str_replace($baseRoot, $baseUrl, $avatar);
        $avatar = str_replace("\\", "/", $avatar);
        return "{$this->baseUri}{$avatar}";
    }
}